package edu.imac.angryfood.shapes;

import org.jbox2d.common.Vec2;
import org.jbox2d.common.XForm;

public class Polygon extends PolygonBasedShape {
	/**
	 * Constructor : Create a new polygon shape
	 */
	public Polygon() {
		this(DEFAULT_DENSITY, DEFAULT_RESTIUTION, DEFAULT_FRICTION);
	}

	/**
	 * Constructor with the density
	 * @param density : density of the polygon we want to create
	 */
	public Polygon(float density) {
		this(density, DEFAULT_RESTIUTION, DEFAULT_FRICTION);
	}

	/**
	 * Constructor with the density and the resitution
	 * @param density : density of the polygon we want to create
	 * @param resitution : resitution of the polygon we want to create
	 */
	public Polygon(float density, float resitution) {
		this(density, resitution, DEFAULT_FRICTION);
	}

	/**
	 * Constructor with the density, the resitution and the friction
	 * @param density : density of the polygon we want to create
	 * @param resitution : resitution of the polygon we want to create
	 * @param friction : friction of the polygon we want to create
	*/
	public Polygon(float density, float restitution, float friction) {
		getDef().density = density;
		getDef().restitution = restitution;
		getDef().friction = friction;
		slickShape = new org.newdawn.slick.geom.Polygon();
	}

	/**
	 * Add a Point to the polygon
	 * @param x : x of the point
	 * @param y : y of the point
	 */
	public void addPoint(float x, float y) {
		getDef().addVertex(new Vec2(x, y));
	}

	/**
	 * Returns the number of points
	 * @return the number of points
	 */
	public int getPointCount() {
		return getDef().getVertexCount();
	}

	/**
	 * Return the X of the point
	 * @param i : position of the point
	 * @return the X of the point
	 */
	public float getPointX(int i) {
		return getDef().vertices.get(i).x;
	}

	/**
	 * Return the Y of the point
	 * @param i : position of the point
	 * @return the Y of the point
	 */
	public float getPointY(int i) {
		return getDef().vertices.get(i).y;
	}

	/**
	 * Move the rectangle away from the center of it's potential body. The rectangle will still 
	 * be positioned based on it's center but will be offset from the body's center by the given 
	 * value, and rotated by the angle given.
	 * 
	 * @param x The horizontal axis offset
	 * @param y The vertical axis offset
	 * @param angle
	 * @return This rectangle for chaining operations
	 */
	public PolygonBasedShape setOffset(float x, float y, float angle) {
		applyOffset(-xoffset,-yoffset,-angleOffset);
		xoffset = x;
		yoffset = y;
		angleOffset = angle;
		applyOffset(x,y,angle);
		return this;
	}
	
	/**
	 * Move a shape, apply a offset 
	 * @param x
	 * @param y
	 * @param angle
	 */
	@Override
	protected void applyOffset(float x, float y, float angle) {
		final XForm xf = new XForm();
		xf.position.set(new Vec2(x, y));
		xf.R.set(angle);

		/** Transform vertices and normals **/
		for (int i = 0; i < getDef().getVertexCount(); ++i) {
			XForm.mulT(xf, getDef().vertices.get(i));
		}

	}
}
